from typing import Callable
import json
import socketio

from CloudEngine.Render.Application import Application

sio = socketio.AsyncClient()

state = {"name": "engine_server"}

app: Application
callback: Callable


async def res_err(Tag, ReplyTo, errmsg):
    await sio.emit(
        "command_res",
        {
            "Tag": Tag,
            "ReplyTo": ReplyTo,
            "Status": -1,
            "Result": "",
            "Errmsg": errmsg,
            "Req": 0,
            "Res": 1,
        },
    )


async def res_success(Tag, ReplyTo, Result):
    await sio.emit(
        "command_res",
        {
            "Tag": Tag,
            "ReplyTo": ReplyTo,
            "Status": 0,
            "Result": Result,
            "Errmsg": "",
            "Req": 0,
            "Res": 1,
        },
    )


async def connect_client(url):
    await sio.connect(url, transports=["websocket"])
    await sio.wait()


async def disconnect_client(self):
    await sio.disconnect()


@sio.event
async def connect():
    print("connected to server")
    await sio.emit("join", "engine_server")


@sio.event
async def disconnect():
    return 0


@sio.on("MouseMove")
async def mouse_move(json_str):
    data = json.loads(json_str)
    x = data.get("x")
    y = data.get("y")
    ctrl = data.get("ctrl") == "1"
    shift = data.get("shift") == "1"
    if app.accept_event():
        app.mouse_move(x, y, ctrl, shift)
        app.render()


@sio.on("LeftButtonPress")
async def left_button_press(json_str):
    data = json.loads(json_str)
    x = data.get("x")
    y = data.get("y")
    ctrl = data.get("ctrl") == "1"
    shift = data.get("shift") == "1"
    app.left_button_press(x, y, ctrl, shift)


@sio.on("LeftButtonRelease")
async def left_button_release(json_str):
    data = json.loads(json_str)
    x = data.get("x")
    y = data.get("y")
    app.left_button_release(x, y)


@sio.on("RightButtonPress")
async def right_button_press(json_str):
    print("右键来了")
    data = json.loads(json_str)
    x = data.get("x")
    y = data.get("y")
    app.right_button_press(x, y)


@sio.on("RightButtonRelease")
async def right_button_release(json_str):
    data = json.loads(json_str)
    x = data.get("x")
    y = data.get("y")
    app.right_button_release(x, y)


@sio.on("MouseWheel")
async def mouse_wheel(json_str):
    data = json.loads(json_str)
    dx = data.get("dx")
    dy = data.get("dy")
    app.mouse_wheel(dx, dy)
    app.render()


@sio.on("UpdateView")
async def update_view(json_str):
    app.render()


@sio.on("command")
async def command(json_str):
    if callback is not None:
        await callback(json.loads(json_str))
